-- ***********************************************
-- * Gaea Subturn
-- ***********************************************
--------
function features_gaea_subturn()

	if not Attack.act_temporary(0) or Attack.act_is_spell(0, "spell_phantom") then  -----if not Attack.act_temporary(0) then

		local mana = Attack.val_restore(0,"mana")
		mana = mana_start(0,mana)
		local mp_lv = Attack.val_restore(0,"mana_lv")
		local enemy_ai = Attack.val_restore(0,"enemy_ai")
		local bonus = 1
		local udcount={}

		if (Attack.act_is_spell(0, "spell_magic_bondage")
		or Attack.act_is_spell(0, "special_stupid")) then

			Attack.act_del_spell(0, "spell_magic_bondage")
			Attack.act_del_spell(0, "special_stupid")

			if Attack.act_size(0)>1 then

				Attack.log(0.001,"add_blog_antibondage", "name",blog_side_unit(0,1))
			end
		end

		if Attack.act_is_spell(0, "ks_effect_faith_shield")
		and (Attack.act_is_spell(0, "effect_poison")
		or Attack.act_is_spell(0, "effect_burn")
		or Attack.act_is_spell(0, "feat_bleeding")) then

			Attack.act_del_spell(0,"effect_poison")
			Attack.act_del_spell(0,"effect_burn")
			Attack.act_del_spell(0,"feat_bleeding")

			if Attack.act_size(0)>1 then

				Attack.log(0.001,"add_blog_antisubdmg", "name",blog_side_unit(0,1))
			end
		end

		if enemy_ai == nil then
			local bel = Attack.act_belligerent(0)
			if bel == 0 or bel == 4 then
				local duration = tonumber(Attack.val_restore(0,"fs_dur"))
				local shield_hp  = tonumber(Attack.val_restore(0,"fs_hp"))*tonumber(Attack.act_size(0))
				Attack.act_apply_spell_begin(0, "ks_effect_faith_shield", duration, false)
				Attack.act_posthitslave(0, "post_special_faith_shield", duration)
				Attack.val_store(0,"shield_hp",shield_hp)
				Attack.act_apply_spell_end()
				Attack.val_store(0,"enemy_ai",1)
			end
		end

		if mp_lv == nil then
			mp_lv = 1
		end

		if mana < 20 then
			mp_lv = 1
		elseif mana >= 20 and mana < 40 then
			mp_lv = 2
		elseif mana >= 40 then
			mp_lv = 3
		end

		Attack.val_store(0,"mana",mana)
		Attack.val_store(0,"mana_lv",mp_lv)
		Attack.val_store(0,"mp_given",1)

		Attack.act_apply_spell_begin( 0, "ks_effect_mana", math.min(3,mp_lv), false )

		if mp_lv < 2 then
			Attack.act_enable_attack(0,"blue",false)

		elseif mp_lv >= 2 then
			Attack.act_enable_attack(0,"blue")
		end

		if mp_lv < 3 then
			Attack.act_enable_attack(0,"illusion",false)

		elseif mp_lv >= 3 then
			Attack.act_enable_attack(0,"illusion")
		end
	
		Attack.act_apply_spell_end()
 		Attack.act_posthitmaster(0, "mana_posthitmaster" ,100)
		Attack.act_posthitslave(0,"mana_posthitslave",100)

		for i=1,Attack.act_count()-1 do
			if Attack.act_ally(i) and Attack.act_feature(i,"undead") then

				table.insert(udcount, i)
			end
		end

		if table.getn(udcount) > 0 then
			Attack.act_attach_modificator(0, "moral", "anti_undead_mod", bonus,0,0,100)
		end

		if (Game.DayTime()<2 and not Game.LocType("dungeon"))
		or (Game.DayTime()<2 and not Game.LocType("cemetery")) then

			for i=1,Attack.act_count()-1 do

				if Attack.act_ally(i)
				and not (Attack.act_temporary(i)
				or Attack.act_name(i)=="gaea")
				and not Attack.act_feature(i,"mech,golem,undead,demon,pawn,boss,lizardead") then

					Attack.act_attach_modificator(i, "moral", "amaa_mod", bonus,0,0,100)
					Attack.act_attach_modificator(i, "initiative", "aiaa_mod", bonus,0,0,100)
					Attack.act_attach_modificator(i, "speed", "asaa_mod", bonus,0,0,100)
				end
			end
		end

	elseif Attack.act_temporary(0) then
		Attack.act_enable_attack(0,"respawn",false)
		Attack.act_enable_attack(0,"blue",false)
		Attack.act_enable_attack(0,"illusion",false)
	end
	return true
end

function features_gaea_ondamage(wnm,ts,dead)

	if dead then

		for i=1,Attack.act_count()-1 do

			Attack.act_del_modificator(i, "amaa_mod")
			Attack.act_del_modificator(i, "aiaa_mod")
			Attack.act_del_modificator(i, "asaa_mod")
		end

		Attack.act_del_modificator(0, "anti_undead_mod")
	end
	return true
end

function faith_shield_hp_max()

	local shield_hp_max = Attack.val_restore(0,"shield_hp")
	text = tostring(shield_hp_max)
	return text
end

function post_special_faith_shield(damage,addrage,attacker,receiver,minmax,except_this)

	if minmax==0
	and damage>0
	and Attack.act_is_spell(receiver,"ks_effect_faith_shield") then

		local shield_hp = tonumber(Attack.val_restore(receiver,"shield_hp"))
		local subdmg = math.floor(damage - damage*.2)
		shield_hp = shield_hp - subdmg

		if shield_hp <= 0 then

			damage = math.floor(damage*.2) + shield_hp
			Attack.act_del_spell(receiver,"ks_effect_faith_shield")
			Attack.act_posthitslave(receiver,"post_special_faith_shield",0)
			Attack.atom_spawn(receiver, 0, "effect_s_protection")
			Attack.val_store(receiver,"shield_hp",0)

			if Attack.act_size(receiver)>1 then
				Attack.log(0.001,"add_blog_faith_shield_break", "name",blog_side_unit(receiver,1))
			end

		elseif shield_hp > 0 then

			damage = math.floor(damage*.2)
			Attack.val_store(receiver,"shield_hp",shield_hp)
			if Attack.act_size(receiver)>1 then

				Attack.log(0.001,"add_blog_faith_shield_hp", "name",""..blog_side_unit(receiver,1),"special",""..subdmg,"special2",""..shield_hp)
			end
		end
	end
	return damage,addrage
end
--------
-- ***********************************************
-- * Malcanthet Subturn
-- ***********************************************
--------
function features_malcanthet_subturn()

	if not Attack.act_temporary(0) or Attack.act_is_spell(0, "spell_phantom") then  -----if not Attack.act_temporary(0) then

		local count = 0
		local bonus = 1
		local bonus2 = 2
		local duration = 100
		local bel = Attack.act_belligerent(0)
		local hucount={}

		if (Attack.act_is_spell(0, "spell_magic_bondage")
		or Attack.act_is_spell(0, "special_stupid")) then

			Attack.act_del_spell(0, "spell_magic_bondage")
			Attack.act_del_spell(0, "special_stupid")

			if Attack.act_size(0)>1 then

				Attack.log(0.001,"add_blog_antibondage", "name",blog_side_unit(0,1))
			end
		end

		local sid = Attack.val_restore(0,"servant_id")
		if sid~=0 and sid~="1111111" then

			local act = find_unit_by_uid(tonumber(sid))
			if act~= nil then

				if Attack.act_belligerent(act) then

					if ((Attack.act_is_spell(0, "ks_effect_soul_link_master") and not Attack.act_is_spell(act, "ks_effect_soul_link_servant"))
					or (Attack.act_is_spell(act, "ks_effect_soul_link_servant") and not Attack.act_is_spell(0, "ks_effect_soul_link_master"))) then

						Attack.act_del_spell(0, "ks_effect_soul_link_master" )
						Attack.act_del_spell(act, "ks_effect_soul_link_servant" )
						Attack.act_posthitslave(0,"post_master_soul_link",0)
						Attack.act_posthitslave(act,"post_servant_soul_link",0)
						Attack.val_store(0,"servant_id",0)
						Attack.val_store(act,"master_id",0)
					end
				end

				if Attack.act_is_spell(0, "ks_effect_soul_link_master")
				and (Attack.act_is_spell(0, "effect_poison")
				or Attack.act_is_spell(0, "effect_burn")
				or Attack.act_is_spell(0, "feat_bleeding")) then

					Attack.act_del_spell(0,"effect_poison")
					Attack.act_del_spell(0,"effect_burn")
					Attack.act_del_spell(0,"feat_bleeding")

					if Attack.act_size(0)>1 then

						Attack.log(0.001,"add_blog_antisubdmg", "name",blog_side_unit(0,1))
					end
				end

				if Attack.act_is_spell(act, "ks_effect_soul_link_servant")
				and (Attack.act_is_spell(act, "effect_poison")
				or Attack.act_is_spell(act, "effect_burn")
				or Attack.act_is_spell(act, "feat_bleeding")) then

					Attack.act_del_spell(act,"effect_poison")
					Attack.act_del_spell(act,"effect_burn")
					Attack.act_del_spell(act,"feat_bleeding")

					if Attack.act_size(act)>1 then

						Attack.log(0.001,"add_blog_antisubdmg", "name",blog_side_unit(act,1))
					end
				end
			end
		end

		local mana = Attack.val_restore(0,"mana")
		mana = mana_start(0,mana)
		local mp_lv = Attack.val_restore(0,"mana_lv")
		local enemy_ai = Attack.val_restore(0,"enemy_ai")

		if enemy_ai == nil then
			if bel == 0 or bel == 4 then
				local humcount = {}
				for i=1,Attack.act_count()-1 do
					if Attack.act_belligerent(i)
					and Attack.act_feature(i,"humanoid")
					and not Attack.act_temporary(i)
					and not Attack.act_is_spell(i, "spell_hypnosis")
					and not Attack.act_is_spell(i, "ks_effect_soul_link_servant") then
						table.insert(humcount, i)
					end
				end
				if table.getn(humcount) > 0 then
					local act = humcount[Game.CurLocRand(1,table.getn(humcount))]
					local duration = 100 
					local master_id = Attack.act_uid(Attack.get_caa(0))
					local servant_id = Attack.act_uid(Attack.get_caa(act))
					Attack.val_store(act,"master_id",master_id)
					Attack.val_store(0,"servant_id",servant_id)
					Attack.act_apply_spell_begin(0, "ks_effect_soul_link_master", -duration, false)
					Attack.act_apply_spell_begin(act, "ks_effect_soul_link_servant", -duration, false)
					Attack.act_posthitslave(0,"post_master_soul_link",duration)
					Attack.act_posthitslave(act,"post_servant_soul_link",duration)
  					Attack.act_apply_spell_end()
				end
			Attack.val_store(0,"enemy_ai",1)	
			end
		end

		if Game.DayTime()>1 or Game.LocType("dungeon") then
			for i=1,Attack.act_count()-1 do
				if Attack.act_ally(i)
				and not (Attack.act_temporary(i)
				or Attack.act_name(i)=="malcanthet")
				and Attack.act_feature(i,"humanoid") then
					Attack.act_attach_modificator(i, "moral", "mmaa_mod", bonus,0,0,100)
					Attack.act_attach_modificator(i, "initiative", "miaa_mod", bonus,0,0,100)
					Attack.act_attach_modificator(i, "speed", "msaa_mod", bonus,0,0,100)
				end
				if Attack.act_ally(i)
                                and Attack.act_feature(i,"humanoid") then
					table.insert(hucount, i)
				end
			end
			if table.getn(hucount) > 0 then
				Attack.act_attach_modificator(0, "moral", "mmma_mod", bonus,0,0,100)
				Attack.act_attach_modificator(0, "initiative", "mima_mod", bonus,0,0,100)
				Attack.act_attach_modificator(0, "speed", "msma_mod", bonus,0,0,100)
			end
		end
		if bel == 1 or bel == 2 then
			for i=1,Attack.act_count()-1 do
				if Attack.act_ally(i)
				and not Attack.act_temporary(i)
				and Attack.act_feature(i,"humanoid") then
					if (Attack.act_race(i,"human") or Attack.act_race(i,"elf") or Attack.act_race(i,"orc")) then
						Attack.act_attach_modificator(i, "moral", "anitdemon_mod", bonus,0,0,100)
					elseif Attack.act_race(i,"dwarf") then
						Attack.act_attach_modificator(i, "moral", "anitdemon_mod", bonus2,0,0,100)
					end
				end
			end
		end

  if Attack.act_name(0) == "malcanthet" then
		if mp_lv == nil then
			mp_lv = 1
		end

		if mana < 20 then
			mp_lv = 1
		elseif mana >= 20 and mana < 40 then
			mp_lv = 2
		elseif mana >= 40 then
			mp_lv = 3
		end

		Attack.val_store(0,"mana",mana)
		Attack.val_store(0,"mana_lv",mp_lv)
		Attack.val_store(0,"mp_given",1)

		Attack.act_apply_spell_begin(0, "ks_effect_mana", math.min(3,mp_lv), false)

		if mp_lv < 2 then
			Attack.act_enable_attack(0,"blue",false)

		elseif mp_lv >= 2 then
			Attack.act_enable_attack(0,"blue")
		end

		if mp_lv < 3 then
			Attack.act_enable_attack(0,"illusion",false)

		elseif mp_lv >= 3 then
			Attack.act_enable_attack(0,"illusion")
		end
	
		Attack.act_apply_spell_end()
 		Attack.act_posthitmaster(0, "mana_posthitmaster" ,100)
		Attack.act_posthitslave(0,"mana_posthitslave",100)
	end

	elseif Attack.act_temporary(0) then
		Attack.act_enable_attack(0,"cast_blasphemous",false)
		Attack.act_enable_attack(0,"blue",false)
		Attack.act_enable_attack(0,"illusion",false)
	end

	return true
end

function features_malcanthet_ondamage(wnm,ts,dead)

	if dead then

		for i=1,Attack.act_count()-1 do
			Attack.act_del_modificator(i, "mmaa_mod")
			Attack.act_del_modificator(i, "miaa_mod")
			Attack.act_del_modificator(i, "msaa_mod")
			Attack.act_del_modificator(i, "antidemon_mod")
		end
		Attack.act_del_modificator(0, "mmma_mod")
		Attack.act_del_modificator(0, "mima_mod")
		Attack.act_del_modificator(0, "msma_mod")
	end
	return true
end
--------
-- ***********************************************
-- * Malcanthet Soul Link
-- ***********************************************
--------
function post_master_soul_link(damage,addrage,attacker,receiver,minmax,userdata)

	if minmax == 0
	and damage > 0
	and attacker~=nil
	and Attack.act_name(attacker) ~= "servant_soul_link" then

		local sid = Attack.val_restore(receiver,"servant_id")
		if sid~=0 and sid~="1111111" then

			local servant = find_unit_by_uid(tonumber(sid))
			if servant~= nil then

				Attack.atom_spawn(receiver,0,"effect_goblin_life",0)
				local a = Attack.atom_spawn(servant, 0, "master_soul_link")
				Attack.val_store(a, "damage", math.floor(damage/2))
				Attack.val_store(a, "belligerent", Attack.act_belligerent(receiver))
				Attack.val_store(a, "receiver_uid", Attack.act_uid(receiver))
				Attack.val_store(a, "target_uid", Attack.act_uid(servant))
				Attack.resort(Attack.get_caa(a))
				damage = math.floor(damage/3)
				addrage = math.floor(addrage/3)
			end
		end
	end
	return damage, addrage
end

function post_master_soul_link_share()

	local act = find_unit_by_uid(Attack.val_restore("target_uid"))
	if act ~= nil then
		local a = Attack.atom_spawn(act,0,"effect_goblin_life",0)
		local dmgt = Attack.aseq_time(a, "x")
		Attack.atk_set_damage("astral", Attack.val_restore("damage"))
		common_cell_apply_damage(act, dmgt)
	end
	Attack.act_remove(0, 0)
	return true
end

function post_servant_soul_link(damage,addrage,attacker,receiver,minmax,userdata)

	if minmax == 0
	and damage > 0
	and attacker~=nil
	and Attack.act_name(attacker) ~= "master_soul_link" then

		local mid = Attack.val_restore(receiver,"master_id")
		if mid~=0 and mid~="1111111" then

			local master = find_unit_by_uid(tonumber(mid))
			if master~= nil then

				Attack.atom_spawn(receiver,0,"effect_goblin_life",0)
				local a = Attack.atom_spawn(master, 0, "servant_soul_link")
				Attack.val_store(a, "damage", math.floor(damage/2))
				Attack.val_store(a, "belligerent", Attack.act_belligerent(receiver))
				Attack.val_store(a, "receiver_uid", Attack.act_uid(receiver))
				Attack.val_store(a, "target_uid", Attack.act_uid(master))
				Attack.resort(Attack.get_caa(a))
			end
		end
	end
	return damage, addrage
end

function post_servant_soul_link_share()

	local act = find_unit_by_uid(Attack.val_restore("target_uid"))
	if act ~= nil then
		local a = Attack.atom_spawn(act,0,"effect_goblin_life",0)
		local dmgt = Attack.aseq_time(a, "x")
  		local b = Attack.atom_spawn(act, dmgt, "effect_total_cure")
  		local dmgt1 = Attack.aseq_time(b, "x")
		local heal = tonumber(Attack.val_restore("damage"))
		local count = tonumber(Attack.act_size(act))
		Attack.cell_resurrect(act, heal, dmgt+dmgt1)
		Attack.act_cure(act, -heal, dmgt+dmgt1)
		count = Attack.act_size(act) - count

		if count == 0 then
			Attack.log(0.001,"add_blog_soul_link_cure", "targets",""..blog_side_unit(act,0),"name",""..blog_side_unit(0,1), "special",""..heal)
		else
			Attack.log(0.001,"add_blog_soul_link_resr", "targets",""..blog_side_unit(act,0),"name",""..blog_side_unit(0,1), "special",""..heal, "special2",""..count)
		end
	end
	Attack.act_remove(0, 0)
	return true
end

function master_soul_link_onremove(target,duration_end)

	if duration_end or Attack.act_hp(target) <= 0 then

		local sid = Attack.val_restore(target,"servant_id")
		if sid~=0 and sid~="1111111" then

			local act = find_unit_by_uid(tonumber(sid))
			if act~= nil then
				if Attack.act_hp(act) > 0 then Attack.act_del_spell(act, "ks_effect_soul_link_servant" ) end
				Attack.act_posthitslave(act,"post_servant_soul_link",0)
				Attack.val_store(target,"servant_id",0)
				Attack.val_store(act,"master_id",0)
			end
		end
	end
	return true
end

function servant_soul_link_onremove(target,duration_end)

	if duration_end or Attack.act_hp(target) <= 0 then

		local mid = Attack.val_restore(target,"master_id")
		if mid~=0 and mid~="1111111" then

			local act = find_unit_by_uid(tonumber(mid))
			if act~= nil then
				if Attack.act_hp(act) > 0 then Attack.act_del_spell(act, "ks_effect_soul_link_master" ) end
				Attack.act_posthitslave(act,"post_master_soul_link",0)
				Attack.val_store(target,"master_id",0)
				Attack.val_store(act,"servant_id",0)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Cabalist Subturn
-- ***********************************************
--------
function features_cabalist_subturn()

	if not Attack.act_temporary(0) or Attack.act_is_spell(0, "spell_phantom") then  -----if not Attack.act_temporary(0) then

		local mana = Attack.val_restore(0,"mana")
		mana = mana_start(0,mana)
		local mp_lv = Attack.val_restore(0,"mana_lv")
		local tocount={}

		if (Attack.act_is_spell(0, "spell_magic_bondage")
		or Attack.act_is_spell(0, "special_stupid")) then

			Attack.act_del_spell(0, "spell_magic_bondage")
			Attack.act_del_spell(0, "special_stupid")

			if Attack.act_size(0)>1 then

				Attack.log(0.001,"add_blog_antibondage", "name",blog_side_unit(0))
			end
		end

		for i=1,Attack.act_count()-1 do
			if Attack.act_enemy(i) and Attack.act_is_spell(i, "effect_counterspell") then
				for k=0,Attack.act_spell_count(i)-1 do
					local spell_name=Attack.act_spell_name(i,k)
					local spell_type=Logic.obj_par(spell_name,"type")
					if spell_type=="bonus"
					and string.find(spell_name,"^totem_")==nil
					and string.find(spell_name,"^ks_effect_")==nil
					and spell_name ~= "spell_slime_glot"
					and spell_name ~= "spell_phantom" then
						takeoff_spells(i, "bonus")
						Attack.log(0.001,"add_blog_remove_spell", "target",""..blog_side_unit(i,1))
					end
				end
			end
		end

		local cstgt_id = Attack.val_restore(0,"cstgt_id")
		if cstgt_id~=0 and cstgt_id~="1111111" then

			local act = find_unit_by_uid(tonumber(cstgt_id))
			if act~= nil and not Attack.act_is_spell(act, "effect_counterspell") then
				Attack.act_del_spell(act, "effect_counterspell")
				Attack.val_store(0,"cstgt_id",0)
			end
		end

		if mp_lv == nil then
			mp_lv = 1
		end

		if mana < 20 then
			mp_lv = 1
		elseif mana >= 20 and mana < 40 then
			mp_lv = 2
		elseif mana >= 40 then
			mp_lv = 3
		end

		Attack.val_store(0,"mana",mana)
		Attack.val_store(0,"mana_lv",mp_lv)
		Attack.val_store(0,"mp_given",1)

		Attack.act_apply_spell_begin( 0, "ks_effect_mana", math.min(3,mp_lv), false )

		if mp_lv < 2 then
			Attack.act_enable_attack(0,"lay_egg",false)

		elseif mp_lv >= 2 then
			Attack.act_enable_attack(0,"lay_egg")
		end

		if mp_lv < 3 then
			Attack.act_enable_attack(0,"call_demon",false)

		elseif mp_lv >= 3 then
			Attack.act_enable_attack(0,"call_demon")
		end
	
		Attack.act_apply_spell_end()
 		Attack.act_posthitmaster(0, "mana_posthitmaster" ,100)
		Attack.act_posthitslave(0,"mana_posthitslave",100)
		Attack.act_posthitslave(0,"features_magic_wall",100)

	elseif Attack.act_temporary(0) then
		Attack.act_enable_attack(0,"cast_counterspell",false)
		Attack.act_enable_attack(0,"lay_egg",false)
		Attack.act_enable_attack(0,"call_demon",false)
	end
	return true
end

function features_cabalist_ondamage(wnm,ts,dead)

	if dead then

		local cstgt_id = Attack.val_restore(0,"cstgt_id")
		if cstgt_id~=0 and cstgt_id~="1111111" then

			local act = find_unit_by_uid(tonumber(cstgt_id))
			if act~= nil then
				Attack.act_del_spell(act, "effect_counterspell" )
				Attack.val_store(0,"cstgt_id",0)
			end
		end
	end
	return true
end

function features_magic_wall(damage,addrage,attacker,receiver,minmax,userdata,hitbacking)

	if minmax == 0
	and damage > 0 then

		local mana = Attack.val_restore(receiver,"mana")
		if mana==nil
		or mana < 0 then
			mana = 0
		elseif mana >= 20 and mana <30 then
			damage = math.floor(damage*.8)
			addrage = math.floor(addrage*.8)
		elseif mana >= 30 and mana <40 then
			damage = math.floor(damage*.6)
			addrage = math.floor(addrage*.6)
		elseif mana >= 40 then
			damage = math.floor(damage*.4)
			addrage = math.floor(addrage*.4)
		end
	end
	return damage, addrage
end

function magic_tower_subturn()

	local auto_hitback = Attack.val_restore(0,"auto_hitback")
	local bosscount={}
	for i=1,Attack.act_count()-1 do
		if Attack.act_enemy(i) and Attack.act_feature(i,"boss") then

			table.insert(bcssount, i)
		end
	end

	if table.getn(bosscount) == 0 then

		for k=1,Attack.act_count()-1 do
			if (Attack.act_ally(k) or Attack.act_enemy(k))
			and Attack.act_temporary(k)
			and Attack.act_size(k) > 1
			and not Attack.act_is_spell(k, "summon_master")
			and not Attack.act_is_spell(k, "ks_effect_temporary")
			and not Attack.act_is_spell(k, "ks_effect_temporary_ghost")
			and not Attack.act_is_spell(k, "spell_phantom") then
				Attack.atom_spawn(k, 0, "magic_phantom")
				Attack.act_transparency(k, .7)
				Attack.act_apply_spell_begin(k, "spell_phantom", 2, false)
				Attack.act_apply_spell_end()
				Attack.log(0.001,"add_blog_summon_to_phantom","targets", ""..blog_side_unit(k,1),"name",""..blog_side_unit(0,0))
			end
		end

	elseif table.getn(bosscount) > 0 then

		for k=1,Attack.act_count()-1 do
			if Attack.act_ally(k)
			and Attack.act_temporary(k)
			and Attack.act_size(k) > 1
			and not Attack.act_is_spell(k, "summon_master")
			and not Attack.act_is_spell(k, "ks_effect_temporary_ghost")
			and not Attack.act_is_spell(k, "spell_phantom") then
				Attack.atom_spawn(k, 0, "magic_phantom")
				Attack.act_transparency(k, .7)
				Attack.act_apply_spell_begin(k, "spell_phantom", 2, false)
				Attack.act_apply_spell_end()
				Attack.log(0.001,"add_blog_summon_to_phantom","targets", ""..blog_side_unit(k,1),"name",""..blog_side_unit(0,0))
			end
		end
	end
	local attack = Attack.act_get_par(0,"attack")
	local defense = Attack.act_get_par(0,"defense")
	if attack > 35 then 
		attack = 35;
		Attack.act_set_par(0, "attack", attack);
	end
	if defense > 50 then 
		defense = 50;
		Attack.act_set_par(0, "defense", defense);
	end

	if auto_hitback == nil then
		Attack.val_store(0, "auto_hitback", 1)
	end

	Attack.act_posthitslave(0,"pawn_skin",100)
	Attack.act_posthitslave(0,"post_magic_tower_squelch",100)
	return true
end

function post_magic_tower_squelch(damage,addrage,attacker,receiver,minmax,userdata)

	if minmax == 0
	and damage > 0
	and not hitbacking
	and Attack.act_enemy(receiver)
	and not Attack.act_feature(attacker,"pawn,boss") then

		local auto_hitback = Attack.val_restore(receiver,"auto_hitback")
		local hitbackprotect = Attack.act_get_par(attacker,"hitbackprotect")
		if hitbackprotect == nil then hitbackprotect = 0 end
		if auto_hitback==1
		and hitbackprotect == 0 then

			local a = Attack.atom_spawn(attacker, 0, "magic_tower_squelch")
			Attack.val_store(a, "belligerent", Attack.act_belligerent(receiver))
			Attack.val_store(a, "mt_act_uid", Attack.act_uid(receiver))
			Attack.val_store(a, "mt_tgt_uid", Attack.act_uid(attacker))
			Attack.val_store(receiver, "auto_hitback", 0)
			Attack.resort(Attack.get_caa(a))
		end
	end
	return damage, addrage
end

function magic_tower_selattack()

	local noimm = {}
	for i=1, Attack.act_count()-1 do

		if not Attack.act_feature(i,"magic_immunitet") then
			table.insert(noimm, i)
		end
	end

	if table.getn(noimm) > 0 and Game.CurLocRand(1,100) < 80 then

		return Attack.change_attack(0)
	else
		return Attack.change_attack(1)
	end
end

function magic_tower_squelch()

	Attack.log_label('null')
	local target = find_unit_by_uid(Attack.val_restore("mt_tgt_uid"))
	local act = find_unit_by_uid(Attack.val_restore("mt_act_uid"))
	if act~=nil and target~=nil
	and Attack.act_hp(act)>0 then
		local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
		local duration = tonumber(Attack.get_custom_param("duration"))
		local k = tonumber(Attack.get_custom_param("k"))
		local power = Attack.val_restore(act,"power")
		local freecell = {}
		for c=0,Attack.cell_count()-1 do
			local cell = Attack.cell_get(c)
			if (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)) then
				table.insert(freecell, cell)
			end
		end
		if Game.CurLocRand(1,100) < k
		and not Attack.act_is_spell(target, "spell_ram")
		and not Attack.act_feature(target,"golem,mech,pawn,boss,magic_immunitet") then
			Attack.act_aseq(act,"cast")
			local dmgts = Attack.aseq_time(act,"x")
			ks_dispell(target)
			Attack.act_apply_spell_begin(target, "spell_ram", duration, false)
			Attack.act_apply_par_spell("autofight", 1, 0, 0, duration, false)
			Attack.act_apply_par_spell("hitback", 0, 0, -100, duration, false, 1000)
			Attack.act_apply_spell_end()
			Attack.val_store(target,"initial_tag",actor_name(target))
			local l = 1
			Attack.act_fadeout(target, 0, l)
			Attack.act_change_tag(target,"ram",l)
			Attack.atom_spawn(target, 0, "magic_ram")
			Attack.atom_spawn(target, l - Attack.aseq_time("magic_ram", "x"), "magic_ram", Attack.angleto(target))
			Attack.act_fadeout(target, l, l*2, 1)
			if Attack.act_size(target)>1 then
				Attack.log(0.001,"add_blog_ram_for_magic_tower","targets", ""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1))
			end
		elseif Game.CurLocRand(1,100) < k
		and table.getn(freecell) > 0 then
			local enemies = {}
			local escape,escape2,escape3 = {},{},{}
			for c=1,Attack.act_count()-1 do
				if Attack.act_enemy(c) or Attack.act_feature(c,"boss") then
					table.insert(enemies, c)
				end
			end
			for c=0,Attack.cell_count()-1 do
				local esccount,esccount2,esccount3 = 0,0,0
				local cell = Attack.cell_get(c)
				for k,v in ipairs(enemies) do
					if Attack.cell_dist(v,cell) <=3 then
						esccount = esccount + 1
					end
					if Attack.cell_dist(v,cell) <=2 then
						esccount2 = esccount2 + 1
					end
					if Attack.cell_dist(v,cell) <=1 then
						esccount3 = esccount3 + 1
					end
				end
				if esccount == 0 and (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)) then
					table.insert(escape, cell)
				elseif esccount2 == 0 and (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)) then
					table.insert(escape2, cell)
				elseif esccount3 == 0 and (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)) then
					table.insert(escape3, cell)
				end
			end
			if table.getn(escape) > 0 then
				target = escape[Game.CurLocRand(1,table.getn(escape))]
			elseif table.getn(escape2) > 0 then
				target = escape2[Game.CurLocRand(1,table.getn(escape2))]
			elseif table.getn(escape3) > 0 then
				target = escape3[Game.CurLocRand(1,table.getn(escape3))]
			else
				target = freecell[Game.CurLocRand(1,table.getn(freecell))]
			end
			local nearest_dist, nearest_enemy, ang_to_enemy = 10e10, nil, 0
			for i=1,Attack.act_count()-1 do
				if Attack.act_enemy(i) then
					local d = Attack.cell_dist(act,i)
					if d < nearest_dist then nearest_dist = d; nearest_enemy = i; end
				end
			end
			if nearest_enemy ~= nil then
				ang_to_enemy = Attack.angleto(target, nearest_enemy)
			end
			Attack.act_aseq(act, "telein")
			Attack.atom_spawn(act, 0, "hll_telein")
			local t = Attack.aseq_time(act)
			Attack.act_aseq(act, "teleout" )
			Attack.atom_spawn(target, t, "hll_teleout")
			Attack.act_teleport(act, target, t, ang_to_enemy)
			Attack.log(0.001,"add_blog_teleport_for_magic_tower","name",""..blog_side_unit(act,1))
		else
			Attack.act_aseq(act,"cast")
			local dmgts = Attack.aseq_time(act,"x")
			local physical = Attack.act_get_res(target,"physical")
			local magic = Attack.act_get_res(target,"magic")
			local fire = Attack.act_get_res(target,"fire")
			local poison = Attack.act_get_res(target,"poison")
			local typedmg
			local frame
			if magic <= physical and magic <= fire and magic <= poison then
				typedmg = "magic"
				local a = Attack.atom_spawn(target, dmgts, "magic_lightning")
				local dmgts1 = Attack.aseq_time(a, "x")
				frame = dmgts+dmgts1

				if Game.CurLocRand(1,100) < k then
					effect_shock_attack(target,frame+1,duration)
				end
			elseif physical <= magic and physical <= fire and physical <= poison then
				typedmg = "physical"
				local a = Attack.atom_spawn(target,dmgts,"magic_armageddon_spawn")
				local spawn_shift = Attack.aseq_time(a, "x")+dmgts
				local start_up = Attack.aseq_time("magic_armageddon","w")
				local end_up   = Attack.aseq_time("magic_armageddon","x")
				local start_down = Attack.aseq_time("magic_armageddon","y")
				local end_down   = Attack.aseq_time("magic_armageddon","z")
				local t = dmgts+Game.CurLocRand(100)/100.-1.
				Attack.atom_spawn(target,t,"magic_armageddon")
				local hit_time = t + end_down
				local tx,ty,tz = Attack.act_get_center(target)
				Attack.act_move( t+start_up, t+end_up, target, tx, ty, tz+3)
				Attack.act_rotate( t+end_up, t+start_down, target, Game.Dir2Ang(Attack.act_dir(target))+2*math.pi*(2*math.random(0,1)-1) )
				local t1 = t + lerp(end_up, start_down, 1/6.)
				local t2 = t + lerp(end_up, start_down, 3/6.)
				local t3 = t + lerp(end_up, start_down, 5/6.)
				Attack.act_move( t+end_up, t1, target, tx, ty, tz+2.7)
				Attack.act_move( t1, t2, target, tx, ty, tz+3.3)
				Attack.act_move( t2, t3, target, tx, ty, tz+2.7)
				Attack.act_move( t3, t+start_down, target, tx, ty, tz+3)
				Attack.act_falldown( t+start_down, hit_time, target, tz)
				frame = hit_time
				if Game.CurLocRand(1,100) < k and not Attack.act_feature(target,"freeze_immunitet") then
					effect_freeze_attack(target,frame+1,duration)
				end
			elseif fire <= physical and fire <= magic and fire <= poison then
				typedmg = "fire"
				local a = Attack.atom_spawn(target, dmgts-.5, "effect_fire_cyclone")
				local dmgts1 = Attack.aseq_time(a, "x")
				local b = Attack.atom_spawn(target, dmgts+.6, "effect_fire_torch")
				local dmgts2 = Attack.aseq_time(b, "x")
				frame = dmgts+dmgts1+dmgts2
				if Game.CurLocRand(1,100) < k and not Attack.act_feature(target,"fire_immunitet") then
					effect_burn_attack(target,frame+.3,duration)
				end
			elseif poison <= physical and poison <= magic and poison <= fire then
				typedmg = "poison"
				local a = Attack.atom_spawn(target, dmgts, "magic_skull", Attack.angleto(target))
				local dmgts1 = Attack.aseq_time(a, "x")
				frame = dmgts+dmgts1
				if Game.CurLocRand(1,100) < k then
					effect_poison_attack(target,frame+1,duration)
				end
			end
			Attack.atk_set_damage(typedmg,dmg_min*power,dmg_max*power)
			common_cell_apply_damage(target, frame)
			Attack.log_label("")
		end
	end
	Attack.act_remove(0, 0)
	return true
end
--------
-- ***********************************************
-- * Conjurer Subturn
-- ***********************************************
--------
function features_conjurer_subturn()

	if not Attack.act_temporary(0) or Attack.act_is_spell(0, "spell_phantom") then  -----if not Attack.act_temporary(0) then

		local mana = Attack.val_restore(0,"mana")
		mana = mana_start(0,mana)
		local mp_lv = Attack.val_restore(0,"mana_lv")
		local bonus = 1
		local smcount={}

		if (Attack.act_is_spell(0, "spell_magic_bondage")
		or Attack.act_is_spell(0, "special_stupid")) then

			Attack.act_del_spell(0, "spell_magic_bondage")
			Attack.act_del_spell(0, "special_stupid")

			if Attack.act_size(0)>1 then

				Attack.log(0.001,"add_blog_antibondage", "name",blog_side_unit(0))
			end
		end

		for i=1,Attack.act_count()-1 do

			if Attack.act_enemy(i) and Attack.act_name(i)=="conjurer" then

				table.insert(smcount, i)
			end
		end

		if table.getn(smcount) == 0 then

			for i=1,Attack.act_count()-1 do

				if Attack.act_ally(i)
				and not (Attack.act_temporary(i)
				or Attack.act_name(i)=="conjurer")
				and (Attack.act_name(i)=="spider"
				or Attack.act_name(i)=="spider_fire"
				or Attack.act_name(i)=="spider_undead"
				or Attack.act_name(i)=="spider_venom"
				or Attack.act_name(i)=="snake"
				or Attack.act_name(i)=="snake_green"
				or Attack.act_name(i)=="snake_royal"
				or Attack.act_name(i)=="ghost"
				or Attack.act_name(i)=="ghost2") then

					Attack.act_attach_modificator(i, "moral", "amsm_mod", bonus+1,0,0,100)
					Attack.act_attach_modificator(i, "initiative", "aism_mod", bonus,0,0,100)
					Attack.act_attach_modificator(i, "speed", "assm_mod", bonus,0,0,100)

				elseif Attack.act_enemy(i)
				and not Attack.act_temporary(i)
				and (Attack.act_name(i)=="spider"
				or Attack.act_name(i)=="spider_fire"
				or Attack.act_name(i)=="spider_undead"
				or Attack.act_name(i)=="spider_venom"
				or Attack.act_name(i)=="snake"
				or Attack.act_name(i)=="snake_green"
				or Attack.act_name(i)=="snake_royal"
				or Attack.act_name(i)=="ghost"
				or Attack.act_name(i)=="ghost2") then

					Attack.act_attach_modificator(i, "moral", "emsm_mod", -bonus,0,0,100)
					Attack.act_attach_modificator(i, "initiative", "eism_mod", -bonus,0,0,100)
					Attack.act_attach_modificator(i, "speed", "essm_mod", -bonus,0,0,100)
				end
			end
		else
			for i=1,Attack.act_count()-1 do

				Attack.act_del_modificator(i, "amsm_mod")
				Attack.act_del_modificator(i, "aism_mod")
				Attack.act_del_modificator(i, "assm_mod")
				Attack.act_del_modificator(i, "emsm_mod")
				Attack.act_del_modificator(i, "eism_mod")
				Attack.act_del_modificator(i, "essm_mod")
			end
		end

		if mp_lv == nil then
			mp_lv = 1
		end

		if mana < 20 then
			mp_lv = 1
		elseif mana >= 20 and mana < 40 then
			mp_lv = 2
		elseif mana >= 40 then
			mp_lv = 3
		end

		Attack.val_store(0,"mana",mana)
		Attack.val_store(0,"mana_lv",mp_lv)
		Attack.val_store(0,"mp_given",1)

		Attack.act_apply_spell_begin( 0, "ks_effect_mana", math.min(3,mp_lv), false )

		if mp_lv < 2 then
			Attack.act_enable_attack(0,"call_demon",false)

		elseif mp_lv >= 2 then
			Attack.act_enable_attack(0,"call_demon")
		end

		if mp_lv < 3 then
			Attack.act_enable_attack(0,"lay_egg",false)

		elseif mp_lv >= 3 then
			Attack.act_enable_attack(0,"lay_egg")
		end
	
		Attack.act_apply_spell_end()
 		Attack.act_posthitmaster(0, "mana_posthitmaster" ,100)
		Attack.act_posthitslave(0,"mana_posthitslave",100)
		Attack.act_posthitslave(0,"features_scale_skin",100)

	elseif Attack.act_temporary(0) then
		Attack.act_enable_attack(0,"attack_spell",false)
		Attack.act_enable_attack(0,"call_demon",false)
		Attack.act_enable_attack(0,"lay_egg",false)
	end
	return true
end

function features_conjurer_ondamage(wnm,ts,dead)

	if dead then

		for i=1,Attack.act_count()-1 do

			Attack.act_del_modificator(i, "amsm_mod")
			Attack.act_del_modificator(i, "aism_mod")
			Attack.act_del_modificator(i, "assm_mod")
			Attack.act_del_modificator(i, "emsm_mod")
			Attack.act_del_modificator(i, "eism_mod")
			Attack.act_del_modificator(i, "essm_mod")
		end
	end
	return true
end

function features_scale_skin(damage,addrage,attacker,receiver,minmax)

	if not Attack.act_feature(attacker,"mage")
	and (Attack.cell_dist(attacker,receiver)>1)
	and Attack.act_is_thrower(attacker) then
		damage=damage*.5
		addrage=addrage*.5
	elseif (Attack.atk_name() == "moveattack" or Attack.atk_class() == "moveattack") then
		damage=damage*.5
		addrage=addrage*.5
	end
	return damage, addrage

end

function totem_sorcery_subturn()

	local auto_hitback = Attack.val_restore(0,"auto_hitback")
	local bel = Attack.val_restore(0,"belligerent")
	local check
	if Attack.val_restore("ally")=="1" then check = Attack.act_ally end
	if Attack.val_restore("ally")=="0" then check = Attack.act_enemy end
	if Attack.val_restore("ally")=="-1" then check = Attack.act_chesspiece end
	local owner = {}
	local effect = {}

	for c=1,Attack.act_count()-1 do
		if not check(c, bel)
		and Attack.act_name(c)=="totem_sorcery" then
			table.insert(owner, c)
		end
	end

	local n = Attack.cell_count()
	for j=0,n-1 do

		local i = Attack.cell_get(j)
		for k,v in ipairs(owner) do

			if check(i, bel)
			and not Attack.act_equal(v, i)
			and Attack.cell_dist(v,i) <=3 then

				table.insert(effect, i)
			end
		end
	end

	local n = Attack.cell_count()
	for j=0,n-1 do

		local i = Attack.cell_get(j)

		if Attack.act_is_spell(i, "ks_effect_totem_aura") then

			Attack.act_del_spell(i,"ks_effect_totem_aura")
			Attack.act_posthitslave(i,"post_totem_aura",0)
		end

		for k,v in ipairs(effect) do

			if check(v, bel) then

				Attack.act_apply_spell_begin(v, "ks_effect_totem_aura", -100, false)
				Attack.act_posthitslave(v,"post_totem_aura",100)
				Attack.act_apply_spell_end()
			end
		end
	end

	local attack = Attack.act_get_par(0,"attack")
	local defense = Attack.act_get_par(0,"defense")

	if attack > 25 then 
		attack = 25;
		Attack.act_set_par(0, "attack", attack);
	end
	if defense > 20 then 
		defense = 20;
		Attack.act_set_par(0, "defense", 20)
	end

	if auto_hitback == nil then
		Attack.val_store(0, "auto_hitback", 1)
	end

	Attack.act_posthitslave(0,"pawn_skin",100)
	Attack.act_posthitslave(0,"post_totem_sorcery_squelch",100)
	return true
end

function post_totem_sorcery_squelch(damage,addrage,attacker,receiver,minmax,userdata)

	if minmax == 0
	and damage > 0
	and attacker~=nil
	and not hitbacking
	and Attack.act_enemy(receiver)
	and Attack.cell_dist(receiver,attacker) <=3 then

		local auto_hitback = Attack.val_restore(receiver,"auto_hitback")
		local hitbackprotect = Attack.act_get_par(attacker,"hitbackprotect")
		if hitbackprotect == nil then hitbackprotect = 0 end
		if auto_hitback==1
		and hitbackprotect == 0
		and not Attack.act_feature(attacker,"pawn,boss") then

			local a = Attack.atom_spawn(attacker, 0, "totem_sorcery_squelch")
			Attack.val_store(a, "belligerent", Attack.act_belligerent(receiver))
			Attack.val_store(a, "ts_act_uid", Attack.act_uid(receiver))
			Attack.val_store(a, "ts_tgt_uid", Attack.act_uid(attacker))
			Attack.val_store(receiver, "auto_hitback", 0)
			Attack.resort(Attack.get_caa(a))
		end
	end
	return damage, addrage
end

function totem_sorcery_squelch()

	Attack.log_label('null')
	local target = find_unit_by_uid(Attack.val_restore("ts_tgt_uid"))
	local act = find_unit_by_uid(Attack.val_restore("ts_act_uid"))

	if act~=nil and target~=nil
	and Attack.act_hp(act)>0 then

		Attack.act_aseq(act,"attack")
		local dmgts = Attack.aseq_time(act,"x")
		local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
		local duration = tonumber(Attack.get_custom_param("duration"))
		local k = tonumber(Attack.get_custom_param("k"))
		local power = Attack.val_restore(act,"power")
		local typedmg = "poison"
		local a = Attack.atom_spawn(target, dmgts, "magic_skull", Attack.angleto(target))
		local dmgts1 = Attack.aseq_time(a, "x")
		local frame = dmgts+dmgts1

		if Game.CurLocRand(1,100) < k
		and not Attack.act_feature(target,"golem,mech,pawn,boss") then
			effect_poison_attack(target,frame+1,duration)
		end

		Attack.atk_set_damage(typedmg,dmg_min*power,dmg_max*power)
		common_cell_apply_damage(target, frame)
		Attack.log_label("")
	end
	Attack.act_remove(0, 0)
	return true
end

function post_totem_aura(damage,addrage,attacker,receiver,minmax)

	if (minmax==0)
	and damage>0 then

		damage = damage*1.2
		addrage = addrage*1.2

	end 
	return damage,addrage
end

function post_totem_ghost_debuff(damage,addrage,attacker,receiver,minmax)

	if (minmax==0)
	and damage>0 then

		Attack.act_kill(receiver,false,false)
	end 
	return damage,addrage
end

function totem_sorcery_ondamage(wnm,ts,dead)

	if dead then

		for i=1,Attack.act_count()-1 do

			Attack.act_del_spell(i,"ks_effect_totem_aura")
			Attack.act_posthitslave(i,"post_totem_aura",0)
		end
	end
	return true
end

function totem_sorcery_selattack()
	return Attack.change_attack(0)
end
--------
-- ***********************************************
-- * Udalan Subturn
-- ***********************************************
--------
function features_udalan_subturn()

	if not Attack.act_temporary(0) or Attack.act_is_spell(0, "spell_phantom") then  -----if not Attack.act_temporary(0) then

		local mana = Attack.val_restore(0,"mana")
		mana = mana_start(0,mana)
		local mp_lv = Attack.val_restore(0,"mana_lv")
		local bonus = 1
		local udcount={}

		if (Attack.act_is_spell(0, "spell_magic_bondage")
		or Attack.act_is_spell(0, "special_stupid")) then

			Attack.act_del_spell(0, "spell_magic_bondage")
			Attack.act_del_spell(0, "special_stupid")

			if Attack.act_size(0)>1 then

				Attack.log(0.001,"add_blog_antibondage", "name",blog_side_unit(0,1))
			end
		end

		if mp_lv == nil then
			mp_lv = 1
		end

		if mana < 20 then
			mp_lv = 1
		elseif mana >= 20 and mana < 40 then
			mp_lv = 2
		elseif mana >= 40 then
			mp_lv = 3
		end

		Attack.val_store(0,"mana",mana)
		Attack.val_store(0,"mana_lv",mp_lv)
		Attack.val_store(0,"mp_given",1)

		Attack.act_apply_spell_begin( 0, "ks_effect_mana", math.min(3,mp_lv), false )

		if mp_lv < 2 then
			Attack.act_enable_attack(0,"lay_egg",false)
		elseif mp_lv >= 2 then
			Attack.act_enable_attack(0,"lay_egg")
		end

		if mp_lv < 3 then
			Attack.act_enable_attack(0,"illusion",false)

		elseif mp_lv >= 3 then
			Attack.act_enable_attack(0,"illusion")
		end
		Attack.act_apply_spell_end()
 		Attack.act_posthitmaster(0, "mana_posthitmaster" ,100)
		Attack.act_posthitslave(0,"mana_posthitslave",100)
		Attack.act_posthitmaster(0, "nether_wall_remove" ,100)
		if not Attack.act_is_spell(0, "ks_effect_nether_wall_remove") then
			Attack.act_posthitslave(0,"nether_wall",100)
		end
	elseif Attack.act_temporary(0) then
		local temp = Attack.val_restore(0,"temp")
		if temp ==nil then
			local hp = 600
			Attack.act_set_par(0, "health",hp)
			Attack.act_hp(0, hp)
			Attack.val_store(0,"temp",1)
		end
		Attack.act_enable_attack(0,"blue",false)
		Attack.act_enable_attack(0,"lay_egg",false)
		Attack.act_enable_attack(0,"illusion",false)
	end
	return true
end

function nether_wall_remove(damage,addrage,attacker,receiver,minmax)

	if (minmax==0) and damage > 0
	and (Attack.atk_name(attacker)=="fire_cyclone" or Attack.atk_name(attacker)=="lay_egg")
	and not Attack.act_is_spell(attacker, "ks_effect_nether_wall_remove") then
		local health = Attack.act_get_par(attacker, "health")
		Attack.act_del_spell(attacker, "ks_effect_nether_wall_remove")
		Attack.act_apply_spell_begin(attacker, "ks_effect_nether_wall_remove", -100, true)
		Attack.act_apply_par_spell("health", (health*30)-20, 0, 0, -100, true)
		Attack.act_posthitslave(attacker,"nether_wall",0)
		Attack.act_apply_spell_end()
		if Attack.act_size(attacker)>1 then
			Attack.log(0.001,"add_blog_nether_wall_remove", "name",""..blog_side_unit(attacker,1))
		end
	end 
	return damage,addrage
end

function nether_wall_again(caa)
	if Attack.act_size(caa)>1 then
		Attack.log(0.001,"add_blog_nether_wall_again", "name",""..blog_side_unit(caa,1))
	end
	return true
end

function nether_wall(damage,addrage,attacker,receiver,minmax)

	if (minmax==0)
	and damage>0 then
		if damage <= 100 then
			damage = 1
		else
			damage = damage/100
		end
	end
	return damage,addrage
end

function gate_of_netherworld_selattack()
	return Attack.change_attack(0)
end

function gate_of_netherworld_subturn()

	local auto_hitback = Attack.val_restore(0,"auto_hitback")
	local bel = Attack.val_restore(0,"belligerent")
	local owner = {}
	local effect = {}
	for c=1,Attack.act_count()-1 do
		if Attack.act_ally(c)
		and Attack.act_name(c)=="gate_of_netherworld" then
			table.insert(owner, c)
		end
	end
	for j=0,Attack.cell_count()-1 do
		local count = 0
		local i = Attack.cell_get(j)
		for k,v in ipairs(owner) do
			if Attack.cell_dist(v,i) <=1 then
				table.insert(effect, i)
			end
		end
	end
	for j=0,Attack.cell_count()-1 do
		local i = Attack.cell_get(j)
		if Attack.act_is_spell(i, "ks_effect_gate_aura") then
			Attack.act_del_spell(i,"ks_effect_gate_aura")
		end
		for k,v in ipairs(effect) do
			if Attack.act_enemy(v) then
				local speed = Attack.act_get_par(v,"speed")
				Attack.act_apply_spell_begin(v, "ks_effect_gate_aura", -100, false)
				if speed > 1 then
					Attack.act_apply_par_spell("speed", -(Attack.act_get_par(v,"speed")-1), 0, 0, -100, false)
				end
				Attack.act_apply_spell_end()
			end
		end
	end
	local attack = Attack.act_get_par(0,"attack")
	if attack > 50 then 
		attack = 50;
		Attack.act_set_par(0, "attack", attack);
	end
	return true
end

function gate_duration()

	local duration = tonumber(Attack.val_restore("time_last"))-1
	if duration <= 0 then 
	  	Attack.log("add_blog_temporary","name",blog_side_unit(0,1))
	  	Attack.act_remove(0, 0)
	else
		Attack.log_label('null')
		Attack.val_store(0, "time_last", duration)
		local bel = Attack.val_restore(0,"belligerent")
		local target1,target2,target3,tgt1,tgt2,tgt3
		local owner = {}
		local allies = {}
		local effect,effect2 = {},{}
		for k=1, Attack.act_count()-1 do
			if Attack.act_name(k)=="gate_of_netherworld" then
				table.insert(owner, k)
			end
		end
		for c=0,Attack.cell_count()-1 do
			local cell = Attack.cell_get(c)
			if Attack.cell_dist(0,cell) <=1
			and Attack.act_ally(cell) then
				table.insert(allies, cell)
			end
		end
		for c=0,Attack.cell_count()-1 do
			local count = 0
			local i = Attack.cell_get(c)
			for k,v in ipairs(owner) do
				if Attack.cell_dist(v,i) <=1 then
					count = count + 1
				end
			end
			if count == 0 and (Attack.act_enemy(i) and not Attack.act_feature(i,"pawn,boss")) then
				table.insert(effect, i)
			end
			if count == 0 and (Attack.cell_is_empty(i) and Attack.cell_is_pass(i)) then
				table.insert(effect2, i)
			end
		end
		if table.getn(allies) > 0 then
			for i=1,table.getn(allies) do
				if table.getn(allies) < table.getn(effect) then
					tgt1 = Game.CurLocRand(1,table.getn(allies))
					tgt2 = Game.CurLocRand(1,table.getn(effect))
					target1 = allies[tgt1]
					target2 = effect[tgt2]
					table.remove(allies,tgt1)
					table.remove(effect,tgt2)
				elseif table.getn(allies) < table.getn(effect2) then
					tgt1 = Game.CurLocRand(1,table.getn(allies))
					tgt3 = Game.CurLocRand(1,table.getn(effect2))
					target1 = allies[tgt1]
					target3 = effect2[tgt3]
					table.remove(allies,tgt1)
					table.remove(effect2,tgt3)
				end
				if target1 ~= nil and target2 ~= nil then
					Attack.act_aseq(target1, "telein")
					Attack.act_aseq(target2, "telein")
					Attack.atom_spawn(target1, 0, "hll_telein")
					Attack.atom_spawn(target2, 0, "hll_telein")
					local t = Attack.aseq_time(target1)
					Attack.act_aseq(target1, "teleout")
					Attack.act_aseq(target2, "teleout")
					Attack.atom_spawn(target1, t, "hll_teleout")
					Attack.atom_spawn(target2, t, "hll_teleout")
					Attack.act_teleport(target1, target2, t)
					Attack.log(0.001,"add_blog_gate_nether_warp_unit","name",""..blog_side_unit(0,1),"target",""..blog_side_unit(target1,0),"special",""..blog_side_unit(target2,0))
				elseif target1 ~= nil and target3 ~= nil then
					local nearest_dist, nearest_enemy, ang_to_enemy = 10e10, nil, 0
					for i=1,Attack.act_count()-1 do
						if (Attack.act_enemy(i) and not Attack.act_feature(i,"pawn,boss")) then
							local d = Attack.cell_dist(0,i)

							if d < nearest_dist then
								nearest_dist = d;
								nearest_enemy = i;
							end
						end
					end
					if nearest_enemy ~= nil then
						ang_to_enemy = Attack.angleto(target3,nearest_enemy)
					end
					Attack.act_aseq(target1, "telein")
					Attack.atom_spawn(target1, 0, "hll_telein")
					local t = Attack.aseq_time(target1)
					Attack.act_aseq(target1, "teleout" )
					Attack.atom_spawn(target3, t, "hll_teleout")
					Attack.act_teleport(target1, target3, t, ang_to_enemy)
					Attack.log(0.001,"add_blog_gate_nether_warp_space","name",""..blog_side_unit(0,1),"target",""..blog_side_unit(target1,0))
				end
			end
		end
	end 
	return true
end

function features_fire_shield(damage,addrage,attacker,receiver,minmax,userdata,hitbacking)

	if minmax == 0
	and damage > 0
	and not hitbacking
	and Attack.atk_class() == "moveattack" then
		
		if Game.CurLocRand(1,100)<=102
		and Attack.act_get_res(attacker,"fire")<80
		and (Attack.cell_dist(attacker,receiver)==1) then

			damage = damage*.8
			addrage = addrage*.8

			effect_burn_attack(attacker,0,3,false,receiver)
			if Attack.act_size(attacker) > 1 then
				 Attack.log_special("<label=cpsn_"..Attack.act_name(attacker)..">")
			else
				Attack.log_special("<label=cpn_"..Attack.act_name(attacker)..">")
			end

			Attack.act_damage_addlog(receiver,"add_blog_fire_shield_")
		end	
	end 
	return damage,addrage
end
--------
-- ***********************************************
-- * LSMA023 Subturn
-- ***********************************************
--------
function features_lsma_023_subturn()

	if not Attack.act_temporary(0) or Attack.act_is_spell(0, "spell_phantom") then  -----if not Attack.act_temporary(0) then
		if (Attack.act_is_spell(0, "spell_magic_bondage")
		or Attack.act_is_spell(0, "special_stupid")
		or Attack.act_is_spell(0, "effect_shock")
		or Attack.act_is_spell(0, "effect_sleep")
		or Attack.act_is_spell(0, "effect_freeze")
		or Attack.act_is_spell(0, "effect_stun")
		or Attack.act_is_spell(0,"feat_bleeding")) then
			Attack.act_del_spell(0, "spell_magic_bondage")
			Attack.act_del_spell(0, "special_stupid")
			Attack.act_del_spell(0, "effect_shock")
			Attack.act_del_spell(0, "effect_sleep")
			Attack.act_del_spell(0, "effect_freeze")
			Attack.act_del_spell(0, "effect_stun")
			Attack.act_del_spell(0,"feat_bleeding")
			if Attack.act_size(0)>1 then
				Attack.log(0.001,"add_blog_antidebuff_lsma_023", "name",blog_side_unit(0,1))
			end
		end
		if Attack.act_size(0) < Attack.act_initsize(0)*.3 then
			Attack.act_enable_attack(0,"explosive_device",false)
			Attack.act_enable_attack(0,"gain_mana")
		elseif Attack.act_size(0) < Attack.act_initsize(0)*.5 then
			Attack.act_enable_attack(0,"gain_mana",false)
			Attack.act_enable_attack(0,"explosive_device")
		else
			Attack.act_enable_attack(0,"gain_mana",false)
			Attack.act_enable_attack(0,"explosive_device",false)
		end
	elseif Attack.act_temporary(0) then
		Attack.act_enable_attack(0,"attack_spell",false)
		Attack.act_enable_attack(0,"illusion",false)
		Attack.act_enable_attack(0,"gain_mana",false)
	end
	return true
end

function drone_subturn()

	local bel = Attack.val_restore(0,"belligerent")
	local attack = Attack.act_get_par(0,"attack")
	if attack > 30 then 
		attack = 30;
		Attack.act_set_par(0, "attack", attack);
	end
	return true
end
--------
-- ***********************************************
-- * Astrasz Subturn
-- ***********************************************
--------
function features_astrasz_subturn()

	Attack.act_posthitmaster(0, "features_burn" ,100)
	if not Attack.act_temporary(0) or Attack.act_is_spell(0, "spell_phantom") then  -----if not Attack.act_temporary(0) then
		local skill = Attack.val_restore(0,"skill")
		if skill == nil then
			skill = 10
		elseif skill < 0 then
			skill = 0
		end
		Attack.val_store(0,"skill",skill)
		Attack.val_store(0,"sk_given",1)
		Attack.act_apply_spell_begin( 0, "ks_effect_skill", -100, false )
		if skill == 10 then
			local passcount = {}
			for k=1,Attack.act_count()-1 do

				if Attack.act_enemy(k)
				and not Attack.act_feature(k,"boss")
				and Attack.act_mt(k)==0 then
					table.insert(passcount, k)
				end
			end
			if table.getn(passcount) <= 2 then
				Attack.act_enable_attack(0,"gain_mana",false)
				Attack.act_enable_attack(0,"local_earthquake")
			elseif table.getn(passcount) > 2 then
				local enemy,mtcount = 0,0
				for i=0,Attack.cell_count()-1 do
					local d = Attack.cell_get(i)
					if Attack.act_enemy(d)
					and Attack.cell_dist(0,d) <=1 then
						enemy = enemy + 1
					end
					if Attack.cell_dist(0,d) <=2
					and Attack.act_mt(d)==0
					and not Attack.act_equal(d, 0) then
						if Attack.act_ally(d)
						and Attack.act_name(d)=="astrasz" then
							mtcount = mtcount - 0.5
						elseif Attack.act_ally(d) then
							mtcount = mtcount - 1
						elseif Attack.act_enemy(d) then
							mtcount = mtcount + 1
						end
					end
				end
				if enemy < 2 then
					Attack.act_enable_attack(0,"gain_mana")
					Attack.act_enable_attack(0,"local_earthquake",false)
				elseif enemy >= 2 and mtcount >= 2 then
					Attack.act_enable_attack(0,"gain_mana")
					Attack.act_enable_attack(0,"local_earthquake",false)
				elseif enemy >= 2 and mtcount < 2 then
					Attack.act_enable_attack(0,"gain_mana",false)
					Attack.act_enable_attack(0,"local_earthquake")
				end
			end
		elseif skill < 10 then
			Attack.act_enable_attack(0,"gain_mana",false)
			Attack.act_enable_attack(0,"local_earthquake",false)
		end
 		Attack.act_posthitmaster(0, "skill_posthitmaster" ,100)
		Attack.act_posthitslave(0,"skill_posthitslave",100)
	elseif Attack.act_temporary(0) then
		Attack.act_enable_attack(0,"eat_all",false)
		Attack.act_enable_attack(0,"gain_mana",false)
		Attack.act_enable_attack(0,"local_earthquake",false)
		Attack.val_store(0,"incubation",0)
	end
	return true
end

function features_astrasz_ondamage(wnm,ts,dead)

	Attack.log_label('null')
	if dead then
		local incubation = tonumber(Attack.val_restore(0,"incubation"))
		if incubation == 1 then
			incubation = 0
			local targets,subtargets = {},{}
			for k=0,Attack.cell_count()-1 do
				local cell = Attack.cell_get(k)
				local  dist = tonumber(Attack.val_restore(0,"dist"))
				if dist == nil then dist = 1 end
				if Attack.cell_present(cell)
				and Attack.cell_is_empty(cell)
				and Attack.cell_is_pass(cell) 
				and Attack.cell_dist(0,cell) <=dist then
					table.insert(targets, cell)
					table.insert(subtargets, cell)
				end
			end
			local n = tonumber(Attack.val_restore(0,"number"))
			local p = 5
			local ramdom = Game.CurLocRand(1,100)
			if table.getn(targets) +1 < n then
				n = table.getn(targets) - 1
			end
			if ramdom <25 and n > 1 then
				n = n-1
			elseif ramdom > 90 then
				n = n+1
			end
			if table.getn(targets) >= n and table.getn(targets) > 1 then
				local a = Attack.atom_spawn(0, 2, "effect_local_qrake")
				local dmgt = Attack.aseq_time(a, "x")
				local target = 0
				for i = 1,p do
					local t = Game.CurLocRand(1,table.getn(subtargets))
					subtarget = subtargets[t]
					local frame = dmgt+(i*.7)
					local b = Attack.atom_spawn(subtarget, frame-1, "effect_local_qrake_smoke")
					local frame1 = Attack.aseq_time(b, "x")
					if table.getn(subtargets) > 1 then
						table.remove(subtargets, t)
					end
				end
				for i=1,n do
					local r = Game.CurLocRand(1,table.getn(targets))
					target = targets[r]
					local frame = dmgt+2.5+(i*.5)
					local b = Attack.atom_spawn(target,frame,"effect_incubation")
					local frame1 = Attack.aseq_time(b, "x")
					local belligerent = tonumber(Attack.act_belligerent(0))
					if belligerent == 1 then belligerent = 2 end
					local k = Game.CurLocRand(text_range_dec(Attack.val_restore(0,"k")))
					local units = Attack.val_restore(0,"units")
					local summon_unit = text_dec(units,Game.CurLocRand(1,text_par_count(units)))
					local unit_count = Attack.act_initsize(0)
					local summon_lead = tonumber(Attack.atom_getpar(summon_unit,"leadership"))
					local summon_count = math.floor(2300*unit_count/summon_lead*k/100)
					if summon_count < 1 then summon_count = 1 end
					local nearest_dist, nearest_enemy, ang_to_enemy = 10e10, nil, 0
					for i=1,Attack.act_count()-1 do

						if Attack.act_enemy(i) then
							local d = Attack.cell_dist(target,i)

							if d < nearest_dist then
								nearest_dist = d;
								nearest_enemy = i;
							end
						end
					end
					if nearest_enemy ~= nil then
						ang_to_enemy = Attack.angleto(target,nearest_enemy)
					end
					Attack.act_spawn(target, belligerent, summon_unit, ang_to_enemy, summon_count)
					Attack.act_nodraw(target, true)
					Attack.act_fadeout(target, 0, frame+frame1, 1)
					Attack.act_animate(target, "stop", frame+frame1)
					Attack.act_nodraw(target, false, frame+frame1)
					Attack.resort(target)
					table.remove(targets, r)
				end
				Attack.log(0.001,"add_blog_astrasz_incubation", "target",""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1))
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Skill Power
-- ***********************************************
--------
function gen_skill_count()

	if Attack.act_is_spell(0,"ks_effect_skill") then

		local skill = Attack.val_restore(0,"skill")
		local skill_max = tonumber(Logic.obj_par("ks_effect_skill","skill_max"))

		if skill==nil then
			skill=0
		end

		Attack.val_store(0,"skill",skill)
		text = tostring(skill).."/"..tostring(skill_max)

		return text
	else
		return "0"
	end 
	return "0"
end 

function skill_used_hint()

	text = tostring(Attack.get_custom_param("skill_used"))
	return text
end

function skill_atk_given_hint()

	text = tostring(Logic.obj_par("ks_effect_skill","skill_atk_given"))
	return text
end

function skill_dmg_given_hint()

	text = tostring(Logic.obj_par("ks_effect_skill","skill_dmg_given"))
	return text
end

function skill_posthitmaster(damage,addrage,attacker,receiver,minmax,userdata,dead)
		
	if minmax == 0 and damage > 0 and not hitbacking then
	
		if not (Attack.act_pawn(receiver)
		or Attack.act_feature(receiver,"pawn")) then
	
			local mg_min,mg_max = text_range_dec(Logic.obj_par("ks_effect_skill","skill_atk_given"))
			local skill_max = tonumber(Logic.obj_par("ks_effect_skill","skill_max"))
			local skill = Attack.val_restore(attacker,"skill")

			if skill == nil
			or skill < 0 then
				skill = 0
			end

			local skill_bonus = Game.CurLocRand(mg_min,mg_max)

			if Attack.val_restore(attacker,"sk_given")==1 then

				skill = skill + skill_bonus*tonumber(Attack.val_restore(attacker,"sk_given"))

				if skill > skill_max then
					skill = skill_max
				end

				Attack.val_store(attacker,"sk_given",0)
				Attack.val_store(attacker,"skill",skill)
			end
		end
	end
	return damage,addrage
end

function skill_posthitslave(damage,addrage,attacker,receiver,minmax,userdata,dead)
		
	if minmax == 0 and damage > 0 and not hitbacking then
	
		local mg_min,mg_max = text_range_dec(Logic.obj_par("ks_effect_skill","skill_dmg_given"))
		local skill_max = tonumber(Logic.obj_par("ks_effect_skill","skill_max"))
		local skill = Attack.val_restore(receiver,"skill")

		if skill == nil
		or skill < 0 then
			skill = 0
		end

		local skill_bonus = Game.CurLocRand(mg_min,mg_max)

		if Attack.val_restore(receiver,"sk_given")==1 then

			skill = skill + skill_bonus*tonumber(Attack.val_restore(receiver,"sk_given"))

			if skill > skill_max then
				skill = skill_max
			end

			Attack.val_store(receiver,"sk_given",0)
			Attack.val_store(receiver,"mana",mana)
		end
	end
	return damage,addrage
end
--------
-- ***********************************************
-- * Mana Power
-- ***********************************************
--------
function gen_mana_count()

	if Attack.act_is_spell(0,"ks_effect_mana") then

		local mana = Attack.val_restore(0,"mana")
		local mana_max = tonumber(Logic.obj_par("ks_effect_mana","mana_max"))

		if mana==nil then
			mana=0
		end

		Attack.val_store(0,"mana",mana)
		text = tostring(mana).."/"..tostring(mana_max)

		return text
	else
		return "0"
	end 
	return "0"
end 

function gen_mana_lv()

	if Attack.act_is_spell(0,"ks_effect_mana") then

		local mana = Attack.val_restore(0,"mana")
		local mp_lv = Attack.val_restore(0,"mana_lv")

		if mana==nil
		or mana < 0 then
			mana = 0
		end

		if mp_lv == nil then
			mp_lv = 1
		end

		if mana < 20 then
			mp_lv = 1
		elseif mana >= 20 and mana < 40 then
			mp_lv = 2
		elseif mana >= 40 then
			mp_lv = 3
		end

		Attack.val_store(0,"mana_lv",mp_lv)

		text = tostring(mp_lv)

		return text
	else
		return "0"
	end
	return "0"
end 

function mana_used_hint()

	text = tostring(Attack.get_custom_param("mana_used"))
	return text
end

function mana_atk_given_hint()

	text = tostring(Logic.obj_par("ks_effect_mana","mana_atk_given"))
	return text
end

function mana_dmg_given_hint()

	text = tostring(Logic.obj_par("ks_effect_mana","mana_dmg_given"))
	return text
end

function mp_lv_need()

	text = tostring(Attack.get_custom_param("mp_lv_need"))
	return text
end

function mana_posthitmaster(damage,addrage,attacker,receiver,minmax,userdata,dead)
		
	if minmax == 0 and damage > 0 and not hitbacking then
	
		if not (Attack.act_pawn(receiver)
		or Attack.act_feature(receiver,"pawn")) then
	
			local mg_min,mg_max = text_range_dec(Logic.obj_par("ks_effect_mana","mana_atk_given"))
			local mana_max = tonumber(Logic.obj_par("ks_effect_mana","mana_max"))
			local mana = Attack.val_restore(attacker,"mana")
			local mp_lv = Attack.val_restore(attacker,"mana_lv")

			if mana == nil
			or mana < 0 then
				mana = 0
			end

			if mp_lv == nil then
				mp_lv = 1
			end

			local mana_bonus = Game.CurLocRand(mg_min,mg_max)

			if Attack.val_restore(attacker,"mp_given")==1 then

				mana = mana + mana_bonus*tonumber(Attack.val_restore(attacker,"mp_given"))

				if mana > mana_max then
					mana = mana_max
				end

				if mana < 20 then
					mp_lv = 1
				elseif mana >= 20 and mana < 40 then
					mp_lv = 2
				elseif mana >= 40 then
					mp_lv = 3
				end

				Attack.val_store(attacker,"mp_given",0)
				Attack.val_store(attacker,"mana",mana)
				Attack.val_store(attacker,"mana_lv",mp_lv)
			end
		end
	end
	return damage,addrage
end

function mana_posthitslave(damage,addrage,attacker,receiver,minmax,userdata,dead)
		
	if minmax == 0 and damage > 0 and not hitbacking then
	
		local mg_min,mg_max = text_range_dec(Logic.obj_par("ks_effect_mana","mana_dmg_given"))
		local mana_max = tonumber(Logic.obj_par("ks_effect_mana","mana_max"))
		local mana = Attack.val_restore(receiver,"mana")
		local mp_lv = Attack.val_restore(receiver,"mana_lv")

		if mana == nil
		or mana < 0 then
			mana = 0
		end

		if mp_lv == nil then
			mp_lv = 1
		end

		local mana_bonus = Game.CurLocRand(mg_min,mg_max)

		if Attack.val_restore(receiver,"mp_given")==1 then

			mana = mana + mana_bonus*tonumber(Attack.val_restore(receiver,"mp_given"))

			if mana > mana_max then
				mana = mana_max
			end

			if mana < 20 then
				mp_lv = 1
			elseif mana >= 20 and mana < 40 then
				mp_lv = 2
			elseif mana >= 40 then
				mp_lv = 3
			end

			Attack.val_store(receiver,"mp_given",0)
			Attack.val_store(receiver,"mana",mana)
			Attack.val_store(receiver,"mana_lv",mp_lv)
		end
	end
	return damage,addrage
end

function mana_start(target,mana)

	if target ~=nil and mana ==nil then
		local bel = Attack.act_belligerent(0)
		if bel == 0 or bel == 4 then
			mana = Game.CurLocRand(30,39)
		else 
			mana = 10
		end
	elseif target ~=nil and mana < 0 then
		mana = 0
	end
	return mana
end

function pawn_skin(damage,addrage,attacker,receiver,minmax,userdata,hitbacking)

	if minmax == 0
	and damage>0 then

		damage=damage
		addrage=addrage
	end
	return damage,addrage
end

function features_supply()
	Attack.val_store(0, "auto_hitback", 1)
	return ture
end
--------